0183. typeRoots 和 types 配置
- 1. 🎯 本节内容
- 2. 🫧 评价
- 3. 🤔 typeRoots 配置的作用是什么?
- 4. 🤔 types 配置的作用是什么?
- 5. 🤔 typeRoots 和 types 的区别是什么?
- 6. 🤔 如何配置多个类型目录?
- 7. 🔗 引用
1. 🎯 本节内容
- typeRoots 配置项的作用
- types 配置项的作用
- typeRoots 与 types 的区别
- 多类型目录的配置
- 实际应用场景
2. 🫧 评价
typeRoots 和 types 是控制 TypeScript 类型定义加载的重要配置项。
- typeRoots 指定类型定义文件的查找目录
- types 指定要包含的类型包列表
- 理解两者的区别对于大型项目的类型管理很重要
- 默认情况下不需要配置,TypeScript 会自动查找 @types 目录
- 正确配置可以优化编译性能和避免类型冲突
3. 🤔 typeRoots 配置的作用是什么?
typeRoots 指定类型声明文件的根目录。
3.1. 默认行为
json
// tsconfig.json
// 不配置 typeRoots 时的默认行为
{
"compilerOptions": {
// 默认值:["./node_modules/@types"]
// TypeScript 会自动查找 node_modules/@types 下的所有包
}
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
ts
// 默认情况下,所有 @types 包都会被自动包含
// node_modules/@types/node/index.d.ts ✅ 自动包含
// node_modules/@types/react/index.d.ts ✅ 自动包含
// node_modules/@types/lodash/index.d.ts ✅ 自动包含
import { readFile } from 'fs' // 使用 @types/node
import React from 'react' // 使用 @types/react
import _ from 'lodash' // 使用 @types/lodash1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
3.2. 自定义 typeRoots
json
// tsconfig.json
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types", // npm @types 包
"./types", // 项目自定义类型
"./typings" // 第三方类型
]
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
ts
// 项目结构
/**
* project/
* ├── node_modules/
* │ └── @types/
* │ ├── node/
* │ └── react/
* ├── types/ ← 自定义类型目录
* │ ├── global.d.ts
* │ └── custom-lib/
* │ └── index.d.ts
* ├── typings/ ← 第三方类型目录
* │ └── legacy-lib/
* │ └── index.d.ts
* └── tsconfig.json
*/
// types/global.d.ts
declare const APP_VERSION: string
// types/custom-lib/index.d.ts
declare module 'custom-lib' {
export function doSomething(): void
}
// typings/legacy-lib/index.d.ts
declare module 'legacy-lib' {
export function oldMethod(): void
}
// 使用
import 'custom-lib'
import 'legacy-lib'
console.log(APP_VERSION)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
3.3. 相对路径与绝对路径
json
// tsconfig.json
{
"compilerOptions": {
// 相对路径(相对于 tsconfig.json 文件)
"typeRoots": ["./node_modules/@types", "./types"],
// 绝对路径
"typeRoots": [
"/Users/username/project/node_modules/@types",
"/Users/username/project/types"
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
3.4. 覆盖默认行为
json
// ⚠️ 一旦配置了 typeRoots,默认的 node_modules/@types 不会自动包含
{
"compilerOptions": {
"typeRoots": [
"./types" // ❌ 只会查找 ./types,不会查找 node_modules/@types
]
}
}
// ✅ 正确做法:显式包含 node_modules/@types
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types", // ✅ 必须显式包含
"./types"
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
3.5. 实际应用场景
json
// 场景 1:monorepo 项目
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./packages/shared/types", // 共享类型
"./types" // 项目特定类型
]
}
}
// 场景 2:多环境类型隔离
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./types/common", // 通用类型
"./types/browser" // 浏览器环境类型
// 不包含 ./types/node(Node.js 环境)
]
}
}
// 场景 3:Legacy 项目迁移
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./types", // 新的类型定义
"./legacy-types" // 旧的类型定义
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
4. 🤔 types 配置的作用是什么?
types 指定要包含的具体类型包。
4.1. 默认行为
json
// tsconfig.json
// 不配置 types 时的默认行为
{
"compilerOptions": {
// 默认:包含 typeRoots 下的所有类型包
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
ts
// 默认情况下,typeRoots 下的所有包都会被包含
// node_modules/@types/node ✅ 包含
// node_modules/@types/react ✅ 包含
// node_modules/@types/jest ✅ 包含
// node_modules/@types/lodash ✅ 包含1
2
3
4
5
2
3
4
5
4.2. 指定类型包
json
// tsconfig.json
{
"compilerOptions": {
"types": [
"node", // 只包含 @types/node
"jest" // 只包含 @types/jest
]
// ❌ @types/react 不会被包含
// ❌ @types/lodash 不会被包含
}
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
ts
// ✅ 可以使用 @types/node
import { readFile } from 'fs'
// ✅ 可以使用 @types/jest
describe('test', () => {
it('works', () => {
expect(true).toBe(true)
})
})
// ❌ 不能使用 @types/react(因为没有在 types 中指定)
import React from 'react' // ❌ 错误:找不到模块1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
4.3. 空数组配置
json
// tsconfig.json
{
"compilerOptions": {
"types": [] // 不自动包含任何 @types 包
}
}1
2
3
4
5
6
2
3
4
5
6
ts
// ❌ 所有 @types 包都不会自动包含
import { readFile } from 'fs' // ❌ 找不到类型
import React from 'react' // ❌ 找不到类型
// ✅ 可以通过三斜线指令手动引入
/// <reference types="node" />
import { readFile } from 'fs' // ✅ 现在可以用了1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
4.4. 实际应用场景
json
// 场景 1:Node.js 项目(不需要浏览器类型)
{
"compilerOptions": {
"types": [
"node"
]
}
}
// 场景 2:浏览器项目(不需要 Node.js 类型)
{
"compilerOptions": {
"types": [] // 不包含 @types/node,避免 Node.js 类型污染
}
}
// 场景 3:测试文件配置
// tsconfig.test.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": [
"node",
"jest" // 测试文件需要 jest 类型
]
}
}
// 场景 4:多环境配置
// tsconfig.browser.json
{
"compilerOptions": {
"types": [] // 纯浏览器环境
}
}
// tsconfig.node.json
{
"compilerOptions": {
"types": ["node"] // Node.js 环境
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
5. 🤔 typeRoots 和 types 的区别是什么?
两个配置项的对比和使用场景。
5.1. 核心区别
json
// typeRoots:WHERE to look(在哪里查找)
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types", // 查找目录 1
"./types" // 查找目录 2
]
}
}
// types:WHAT to include(包含什么)
{
"compilerOptions": {
"types": [
"node", // 包含 node
"jest" // 包含 jest
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
5.2. 对比表格
| 特性 | typeRoots | types |
|---|---|---|
| 作用 | 指定类型定义的查找目录 | 指定要包含的类型包 |
| 默认值 | ["./node_modules/@types"] | 包含 typeRoots 下的所有包 |
| 配置后 | 覆盖默认查找路径 | 只包含指定的包 |
| 适用场景 | 添加自定义类型目录 | 精确控制包含的类型 |
| 常见用途 | monorepo、自定义类型 | 环境隔离、性能优化 |
5.3. 组合使用
json
// 同时配置 typeRoots 和 types
{
"compilerOptions": {
// 1. 先在这些目录中查找
"typeRoots": ["./node_modules/@types", "./types"],
// 2. 然后只包含这些包
"types": [
"node",
"custom-lib" // 来自 ./types/custom-lib
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
5.4. 使用决策
ts
/**
* 何时使用 typeRoots?
*
* ✅ 需要添加自定义类型目录
* ✅ monorepo 项目需要共享类型
* ✅ 需要从非标准位置加载类型
*/
// 示例:添加共享类型目录
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./shared/types"
]
}
}
/**
* 何时使用 types?
*
* ✅ 需要精确控制包含的类型
* ✅ 避免环境类型污染(Node.js vs Browser)
* ✅ 优化编译性能(减少类型检查)
* ✅ 解决类型冲突
*/
// 示例:Node.js 项目
{
"compilerOptions": {
"types": ["node"] // 只包含 Node.js 类型
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
5.5. 常见配置模式
json
// 不配置,使用默认行为
{
"compilerOptions": {
// typeRoots: ["./node_modules/@types"](默认)
// types: 所有包(默认)
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
json
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"]
// types: 默认包含所有
}
}1
2
3
4
5
6
2
3
4
5
6
json
{
"compilerOptions": {
"types": ["node"] // 只包含 Node.js
}
}1
2
3
4
5
2
3
4
5
json
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"],
"types": ["node", "custom-lib"]
}
}1
2
3
4
5
6
2
3
4
5
6
6. 🤔 如何配置多个类型目录?
复杂项目的类型目录管理。
6.1. Monorepo 配置
json
// packages/shared/tsconfig.json
{
"compilerOptions": {
"typeRoots": [
"../../node_modules/@types", // 根目录的 @types
"./types" // 共享类型
]
}
}
// packages/app/tsconfig.json
{
"compilerOptions": {
"typeRoots": [
"../../node_modules/@types",
"../shared/types", // 引用共享类型
"./types" // 应用特定类型
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
6.2. 分层类型管理
json
// tsconfig.json
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types", // 第三方类型
"./types/global", // 全局类型
"./types/modules", // 模块类型
"./types/assets" // 资源类型
]
}
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
ts
// 目录结构
/**
* types/
* ├── global/
* │ ├── window.d.ts // 全局 Window 扩展
* │ └── process.d.ts // 全局 Process 扩展
* ├── modules/
* │ ├── custom-lib/
* │ │ └── index.d.ts // 自定义模块类型
* │ └── legacy-lib/
* │ └── index.d.ts
* └── assets/
* ├── images.d.ts // 图片资源类型
* └── styles.d.ts // 样式资源类型
*/
// types/global/window.d.ts
declare global {
interface Window {
APP_CONFIG: {
apiUrl: string
}
}
}
export {}
// types/modules/custom-lib/index.d.ts
declare module 'custom-lib' {
export function doSomething(): void
}
// types/assets/images.d.ts
declare module '*.png' {
const src: string
export default src
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
6.3. 多配置文件
json
// tsconfig.base.json
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./types/common"
]
}
}
// tsconfig.browser.json
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./types/common",
"./types/browser" // 浏览器特定类型
],
"types": [] // 不包含 Node.js 类型
}
}
// tsconfig.node.json
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./types/common",
"./types/node" // Node.js 特定类型
],
"types": ["node"]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
6.4. 动态类型加载
json
// tsconfig.json
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"]
}
}1
2
3
4
5
6
2
3
4
5
6
ts
// 文件级别动态引入
/// <reference types="node" />
/// <reference path="./types/custom.d.ts" />
import { readFile } from 'fs'1
2
3
4
5
2
3
4
5
6.5. 调试配置
bash
# 查看 TypeScript 加载的文件
tsc --listFiles
# 查看类型解析过程
tsc --traceResolution
# 验证配置
tsc --showConfig1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
json
// 输出示例
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"]
},
"files": [
"./node_modules/@types/node/index.d.ts",
"./types/global.d.ts",
"./src/index.ts"
]
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
6.6. 最佳实践
json
// ✅ 推荐配置
{
"compilerOptions": {
// 1. 保持简单,使用默认配置
// 不配置 typeRoots 和 types
// 2. 或者只添加必要的自定义目录
"typeRoots": [
"./node_modules/@types",
"./types"
]
// 3. 只在必要时使用 types
// 如:环境隔离、性能优化
}
}
// ❌ 避免过度配置
{
"compilerOptions": {
"typeRoots": [
"./node_modules/@types",
"./types",
"./typings",
"./declarations",
"./type-definitions",
// ... 过多目录
],
"types": [
"node",
"react",
"jest",
// ... 过多包
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36